package com.wxy.demo.controller;

import cn.hutool.core.util.StrUtil;
import com.wxy.demo.core.AssertUtils;
import com.wxy.demo.core.BizException;
import com.wxy.demo.dao.*;
import com.wxy.demo.dto.DataQueryDto;
import com.wxy.demo.entity.DataSourceInfo;
import com.wxy.demo.entity.InterfaceInfo;
import com.wxy.demo.entity.RequestLog;
import com.wxy.demo.entity.User;
import com.wxy.demo.util.DbUtils;
import com.wxy.demo.util.IpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *
 * </p>
 *
 * @author e-Xiaoyuan.Wang
 * @since 2022/1/14 10:31
 */
@Transactional
@RestController
@RequestMapping("/open-api")
public class OpenApiController {

    @Autowired
    private InterfaceInfoDao interfaceInfoDao;

    @Autowired
    private DataSourceInfoDao dataSourceInfoDao;

    @Autowired
    private UserInterfaceDao userInterfaceDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private RequestLogDao requestLogDao;

    @PostMapping("/getData/{code}")
    private Object getData(HttpServletRequest request, @PathVariable String code, @RequestBody DataQueryDto dto) {
        InterfaceInfo interfaceInfo = interfaceInfoDao.findByCode(code);
        AssertUtils.notNull(interfaceInfo, "接口不存在");
        String ip = IpUtils.getIp(request);
        User user = null;
        try {
            if (!Objects.equals(interfaceInfo.getIsShare(), 1)) {
                AssertUtils.notBlank(dto.getKey(), "缺失密钥参数");
                user = userDao.findByRequestKey(dto.getKey());
                AssertUtils.notNull(user, "无效的密钥");
                AssertUtils.isTrue(StrUtil.isBlank(user.getWhiteList()) ||
                        user.getWhiteList().contains(ip), "无权访问");
                AssertUtils.isTrue(Objects.equals(user.getStatus(), 1), "用户已锁定");
                AssertUtils.isTrue(Objects.equals(interfaceInfo.getStatus(), 1), "接口已停用");
                AssertUtils.notNull(userInterfaceDao.findByUserIdAndInterfaceId(user.getId(), interfaceInfo.getId()),
                        "权限不足");
            }
            DataSourceInfo dataSourceInfo = dataSourceInfoDao.findById(interfaceInfo.getDataSourceId())
                    .orElseThrow(() -> new BizException("数据源不存在"));
            String sql = interfaceInfo.getSql();
            List<Map<String, Object>> data;
            try {
                Connection conn = DbUtils.getConn(dataSourceInfo);
                data = DbUtils.query(conn, sql, dto.getParam());
                DbUtils.close(conn);
            } catch (Exception e) {
                throw new BizException("查询失败");
            }
            // 更新连接次数
            interfaceInfo.setCount(interfaceInfo.getCount() + 1);
            interfaceInfoDao.save(interfaceInfo);
            // 记录日志
            requestLogDao.save(new RequestLog(interfaceInfo.getId(), user != null ? user.getId() : null, new Date(), ip, 1, null));
            return data;
        } catch (BizException e) {
            // 记录日志
            requestLogDao.save(new RequestLog(interfaceInfo.getId(), user != null ? user.getId() : null, new Date(), ip, 2, e.getMessage()));
            return e.getMessage();
        }
    }
}
